package com.code.factory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.code.factory.utils.Const;
import com.code.factory.utils.DBUtil;

import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
import freemarker.template.Version;

public class GeneratorMain {

    private DBUtil dbUtil = new DBUtil();

    /**
     * FreeMarker配置对象
     */
    private Configuration configuration = new Configuration(new Version("2.3.22"));

    /**
     * 要操作的表名数组
     */
    private List<Map<String, String>> tableList = new ArrayList<Map<String, String>>();

    public GeneratorMain() {
        init();
    }

    /**
     * 初始化参数
     */
    private void init() {
        // 初始化FreeMarker模板路径
        String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        try {
            configuration.setDirectoryForTemplateLoading(new File(path + "config/template"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        configuration.setDefaultEncoding("UTF-8");
        // 初始化要操作的表名数组
        for (int i = 0; i < Const.GENTERATOR_TABLES.length; i++) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("name", Const.GENTERATOR_TABLES[i].toUpperCase());
            map.put("nameAs", Const.GENTERATOR_TABLES_AS[i]);
            tableList.add(map);
        }
    }

    private void loadPackageData(Map<String, Object> map) {
        map.put("package_dao", Const.PACKAGE_DAO);
        map.put("package_pojo", Const.PACKAGE_POJO);
        map.put("package_service", Const.PACKAGE_SERVICE);
        map.put("package_service_impl", Const.PACKAGE_SERVICE_IMPL);
//        map.put("package_inf", Const.PACKAGE_INF);
//        map.put("package_inf_impl", Const.PACKAGE_INF_IMPL);
    }

    private void generator(Map<String, Object> data) {
        Writer wr = null;
        Template tempalte;
        try {
            tempalte = configuration.getTemplate("Pojo.ftl");
            wr = new OutputStreamWriter(new FileOutputStream(Const.OUTPUT_POJO_PATH + data.get("pojoName") + ".java"), "UTF-8");
            tempalte.process(data, wr);
            wr.flush();
            tempalte = configuration.getTemplate("Dao.ftl");
            wr = new OutputStreamWriter(new FileOutputStream(Const.OUTPUT_DAO_PATH + data.get("pojoName") + "Dao.java"), "UTF-8");
            tempalte.process(data, wr);
            wr.flush();
            tempalte = configuration.getTemplate("Mapping.ftl");
            wr = new OutputStreamWriter(new FileOutputStream(Const.OUTPUT_MAPPING_PATH + data.get("pojoName") + "Dao.xml"), "UTF-8");
            tempalte.process(data, wr);
            wr.flush();
            tempalte = configuration.getTemplate("Service.ftl");
            wr = new OutputStreamWriter(new FileOutputStream(Const.OUTPUT_SERVICE_PATH + data.get("pojoName") + "Service.java"), "UTF-8");
            tempalte.process(data, wr);
            wr.flush();
            tempalte = configuration.getTemplate("ServiceImpl.ftl");
            wr = new OutputStreamWriter(new FileOutputStream(Const.OUTPUT_SERVICE_IMPL_PATH + data.get("pojoName") + "ServiceImpl.java"), "UTF-8");
            tempalte.process(data, wr);
            wr.flush();
//            tempalte = configuration.getTemplate("Inf.ftl");
//            wr = new OutputStreamWriter(new FileOutputStream(Const.OUTPUT_INF_PATH + "I" + data.get("pojoName") + "Service.java"), "UTF-8");
//            tempalte.process(data, wr);
//            wr.flush();
//            tempalte = configuration.getTemplate("InfImpl.ftl");
//            wr = new OutputStreamWriter(new FileOutputStream(Const.OUTPUT_INF_IMPL_PATH + data.get("pojoName") + "ServiceImpl.java"), "UTF-8");
//            tempalte.process(data, wr);
//            wr.flush();
//            tempalte = configuration.getTemplate("mycat-schema.ftl");
//            wr = new OutputStreamWriter(new FileOutputStream(Const.OUTPUT_MYCAT_CONF_PATH + "schema.xml"), "UTF-8");
//            tempalte.process(data, wr);
//            wr.flush();
        } catch (TemplateNotFoundException e) {
            e.printStackTrace();
        } catch (MalformedTemplateNameException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        } finally {
            if (wr != null) {
                try {
                    wr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void run() {
        for (int i = 0; i < tableList.size(); i++) {
            Map<String, String> map = tableList.get(i);
            String tableName = map.get("name");
            String pojoName = map.get("nameAs");
            Map<String, Object> data = dbUtil.queryMetaData(tableName);
            data.put("pojoName", pojoName);
            data.put("tableName", tableName);
            data.put("pojoNameLowser", firstLowser(pojoName));
            loadPackageData(data);
//            List<String> tables = dbUtil.queryAllTablesData();
//            data.put("tables", tables);
            generator(data);
        }
    }

    /**
     * 首字母小写
     * 
     * @param str
     * @return
     */
    private String firstLowser(String str) {
        String newStr = str.substring(0, 1).toLowerCase() + str.substring(1);
        return newStr;
    }

    public static void main(String[] args) {
        GeneratorMain tools = new GeneratorMain();
        try{
        	tools.run();
        	System.out.println("模板文件生成成功！！！！！");
        }catch(Exception ex){
			ex.printStackTrace();
        }
    }
}
